package cn.js.service.impl;

import cn.js.domain.User;
import cn.js.domain.entity.LoginUser;
import cn.js.mapper.UserMapper;
import cn.js.service.UserService;
import cn.js.utils.JwtUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author Js
 * @Description
 * @Date 2024-11-02 20:46
 * @Version 1.0
 **/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Map<String,Object> login(User user) {

        //不需要连接数据库
        //1、把登录时候的用户名与密码封装 UsernamePasswordAuthenticationToken对象 ,密码校验，自动完成
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        //2、通过AuthenticationManager的authenticate 方法进行用户认证校验
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        //3、如果authenticate为空,则认证不通过，就返回自定义的异常
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("登录失败");
        }
        //如果认证成功，就从authenticate 对象的getPrincipal 方法中拿到认证通过后的登录用户对象
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();

        //生成jwt，使用fastjson的方法，把对象转成字符串
        String loginUserString = JSON.toJSONString(loginUser);
        //调用JWT工具类，生成jwt令牌
        String jwt = JwtUtils.createJWT(loginUserString, null);



        //把生成的token存到redis
        String tokenKey = "token_"+jwt;
        stringRedisTemplate.opsForValue().set(tokenKey,jwt,JwtUtils.JWT_TTL/1000, TimeUnit.SECONDS);

        Map<String,Object> map=new HashMap<>();
        map.put("token",jwt);
        map.put("username",loginUser.getUser().getUserName());

        return map;
    }
}
